#include "SideWidget.h"

SideWidget::SideWidget(QWidget *parent) :
    QWidget(parent) {
    setFixedSize(SIDE_WIDTH, WINDOW_HEIGHT);

    createWidgets();
    createLayouts();
    connectSignalSlots();

    connectionStatus = Network::HOSTING_CONNECTED;
    changeConnectionStatus(Network::DISCONNECTED);
}

ChatWidget * SideWidget::getChatWidget() const {
    return chatTab;
}

void SideWidget::createWidgets() {
    redLabel = new QLabel(tr("R"));
    redLabel->setStyleSheet("QLabel { color : red; font : bold 16px; margin : 10px}");
    redLabel->setAlignment(Qt::AlignHCenter);
    redScoreLabel = new QLabel("0");
    redScoreLabel->setStyleSheet("QLabel { color : red; }");
    redScoreLabel->setAlignment(Qt::AlignHCenter);
    blackLabel = new QLabel(tr("B"));
    blackLabel->setStyleSheet("QLabel { font : bold 16px; margin : 10px}");
    blackLabel->setAlignment(Qt::AlignHCenter);
    blackScoreLabel = new QLabel("0");
    blackScoreLabel->setAlignment(Qt::AlignHCenter);
    currentTurnLabel = new QLabel(tr("Current turn:"));
    currentTurnLabel->setStyleSheet("QLabel {font : bold 14px }");
    turnLabel = new QLabel(tr("Black"));
    statusLabel = new QLabel(tr("Status:"));
    statusLabel->setStyleSheet("QLabel {font : bold 14px }");
    statusLabel->setAlignment(Qt::AlignLeft);
    connectionStatusLabel = new QLabel(tr("Not connected."));
    connectionStatusLabel->setAlignment(Qt::AlignLeft);
    tabWidget = new QTabWidget();
    tabWidget->setMaximumHeight(290);
    hostTab = new HostWidget(tabWidget, &connectionStatus);
    connectTab = new ConnectWidget(tabWidget, &connectionStatus);
    chatTab = new ChatWidget(tabWidget);
    tabWidget->addTab(hostTab, tr("&Host"));
    tabWidget->addTab(connectTab, tr("&Connect"));
    tabWidget->addTab(chatTab, tr("&Chat"));
    disconnectButton = new QPushButton(tr("Disconnect"));
}

void SideWidget::createLayouts() {
    QVBoxLayout * mainLayout = new QVBoxLayout;
    mainLayout->setAlignment(Qt::AlignHCenter);
    QGridLayout * scoreLayout = new QGridLayout;
    scoreLayout->addWidget(redLabel, 0, 0);
    scoreLayout->addWidget(redScoreLabel, 1, 0);
    scoreLayout->addWidget(blackLabel, 0, 1);
    scoreLayout->addWidget(blackScoreLabel, 1, 1);
    QVBoxLayout * turnLayout = new QVBoxLayout;
    turnLayout->addWidget(currentTurnLabel);
    turnLayout->addWidget(turnLabel);
    QVBoxLayout * statusLayout = new QVBoxLayout;
    statusLayout->addWidget(statusLabel);
    statusLayout->addWidget(connectionStatusLabel);
    mainLayout->addItem(scoreLayout);
    mainLayout->addItem(turnLayout);
    mainLayout->addItem(statusLayout);
    mainLayout->addWidget(tabWidget);
    mainLayout->addWidget(disconnectButton);
    mainLayout->setMargin(MARGINS);
    setLayout(mainLayout);
}

void SideWidget::connectSignalSlots() {
    connect(disconnectButton, SIGNAL(clicked()), this, SLOT(disconnectOnClick()));
    connect(this, SIGNAL(connectionStatusChanged(Network::ConnectionStatus)), connectTab, SLOT(changeConnectionStatus(Network::ConnectionStatus)));
    connect(connectTab, SIGNAL(connectionStatusChanged(Network::ConnectionStatus)), this, SLOT(changeConnectionStatus(Network::ConnectionStatus)));
    connect(this, SIGNAL(connectionStatusChanged(Network::ConnectionStatus)), hostTab, SLOT(changeConnectionStatus(Network::ConnectionStatus)));
    connect(hostTab, SIGNAL(connectionStatusChanged(Network::ConnectionStatus)), this, SLOT(changeConnectionStatus(Network::ConnectionStatus)));
    connect(connectTab, SIGNAL(connectionStatusChanged(Network::ConnectionStatus)), hostTab, SLOT(changeConnectionStatus(Network::ConnectionStatus)));
    connect(hostTab, SIGNAL(connectionStatusChanged(Network::ConnectionStatus)), connectTab, SLOT(changeConnectionStatus(Network::ConnectionStatus)));
}

void SideWidget::changeTurn(ConnectFour::Piece piece) {
    if (piece == ConnectFour::NONE) {
        turnLabel->setText(tr("Game over!"));
        turnLabel->setStyleSheet("QLabel { color : black; }");
    } else {
        switch (connectionStatus) {
        case Network::DISCONNECTED:
            if (piece == ConnectFour::RED) {
                turnLabel->setText(tr("Red"));
                turnLabel->setStyleSheet("QLabel { color : red; }");
            } else {
                turnLabel->setText(tr("Black"));
                turnLabel->setStyleSheet("QLabel { color : black; }");
            }
            break;
        case Network::HOSTING_CONNECTED:
            if (piece == ConnectFour::RED) {
                turnLabel->setText(tr("Opponent's turn"));
                turnLabel->setStyleSheet("QLabel { color : red; }");
            } else {
                turnLabel->setText(tr("Your turn"));
                turnLabel->setStyleSheet("QLabel { color : black; }");
            }
            break;
        case Network::CLIENT_CONNECTED:
            if (piece == ConnectFour::RED) {
                turnLabel->setText(tr("Your turn"));
                turnLabel->setStyleSheet("QLabel { color : red; }");
            } else {
                turnLabel->setText(tr("Opponent's turn"));
                turnLabel->setStyleSheet("QLabel { color : black; }");
            }
            break;
        default:
            break;
        }
    }
}

void SideWidget::incrementScore(ConnectFour::Piece piece) {
    if (piece) {
        redScoreLabel->setText(QString::number(++redScore));
    } else {
        blackScoreLabel->setText(QString::number(++blackScore));
    }
}

void SideWidget::disconnectOnClick() {
    changeConnectionStatus(Network::DISCONNECTED);
}

void SideWidget::changeConnectionStatus(Network::ConnectionStatus status) {
    resetScore();
    switch (status) {
    case Network::DISCONNECTED:
        connectionStatusLabel->setText(tr("Not connected."));
        disconnectButton->setEnabled(false);
        setChatTabOnly(false);
        if (connectionStatus == Network::HOSTING_CONNECTED || connectionStatus == Network::CLIENT_CONNECTED) {
            connectionStatus = status;
            emit newConnection(status, NULL);
            emit connectionStatusChanged(status);
        }
        break;
    case Network::HOSTING_WAITING:
        connectionStatusLabel->setText(tr("Waiting on client."));
        disconnectButton->setEnabled(true);
        break;
    case Network::HOSTING_CONNECTED:
        connectionStatusLabel->setText(tr("Connected."));
        disconnectButton->setEnabled(true);
        setChatTabOnly(true);
        emit newConnection(status, hostTab->clientSocket);
        break;
    case Network::CLIENT_WAITING:
        connectionStatusLabel->setText(tr("Connecting to host."));
        disconnectButton->setEnabled(true);
        break;
    case Network::CLIENT_CONNECTED:
        connectionStatusLabel->setText(tr("Connected."));
        disconnectButton->setEnabled(true);
        setChatTabOnly(true);
        emit newConnection(status, connectTab->clientSocket);
        break;
    }
    if (connectionStatus != status) {
        connectionStatus = status;
        emit connectionStatusChanged(status);
    }
}

void SideWidget::resetScore() {
    redScore = 0;
    redScoreLabel->setText("0");
    blackScore = 0;
    blackScoreLabel->setText("0");
}

void SideWidget::setChatTabOnly(bool enabled) {
    if (enabled) {
        tabWidget->setCurrentIndex(CHAT_TAB);
    }
    tabWidget->setTabEnabled(HOST_TAB, !enabled);
    tabWidget->setTabEnabled(CONNECT_TAB, !enabled);
}
